#include "cpcwindow.h"
#include "ui_cpcwindow.h"
#include "pathandname.h"
#include <QtXml>

CpcWindow::CpcWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::CpcWindow)
{
    ui->setupUi(this);
    ui->graphicsView->setScene(&scene);
    ui->comboBox->addItem(tr("RGBA8"));
    ui->comboBox->addItem(tr("RGBA4"));
    ui->comboBox->addItem(tr("RGB565"));
    ui->comboBox->addItem(tr("ARGB8"));
    ui->comboBox->addItem(tr("RGB8"));
    ui->comboBox->addItem(tr("ARGB4"));


    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openCellProject()));
    connect(ui->actionConvertImage, SIGNAL(triggered()), this, SLOT(convertImage()));
    connect(ui->actionConvertSprite, SIGNAL(triggered()), this, SLOT(convertSprite()));
    connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(cexit()));
    connect(ui->actionConvertImageSplit, SIGNAL(triggered()), this, SLOT(convertImageSplit()));

    // ----------------读取设定---------------------
    QString curdir = QApplication::applicationDirPath();
    QFile file(curdir+"\\"+"setting.xml");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
        lastdir = curdir;
    }else{
        QDomDocument pathfile;
        if (!pathfile.setContent(&file)){

        }else{
             QDomElement child = pathfile.documentElement().firstChildElement();
             if (!child.isNull()){
                 if (child.tagName()=="Path"){
                     lastdir = child.attribute("LastPath");
                 }
             }
        }
        file.close();
    }
    // ----------------读取设定结束---------------------
    image_num = 0;
    images = NULL;
    sprite_num = 0;
    sprites = NULL;
    tile_vct = NULL;
}

CpcWindow::~CpcWindow()
{
    delete ui;
}

/** 读取xml文件 */
void CpcWindow::openCellProject(){
    QString filename = QFileDialog::getOpenFileName(this,
                                                    tr("打开xml文件"),
                                                    lastdir,
                                                    tr("CellGameEdit output(*.xml)"));
    PathAndName pan(filename);
    QDomDocument cpxml;
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
        QMessageBox::warning(this, tr("文件不存在"), NULL);
        return ;
    }

    if (!cpxml.setContent(&file)){
        QMessageBox::warning(this, tr("工程文件读取错误"), NULL);
        file.close();
        return ;
    }
    file.close();
    clearWorkSpace();
    /**
      * 解析xml中的内容 (scene_part是每张tile在精灵中的位置，翻转，旋转，缩放等
      * （scene_frame是每帧的内容，data是scene_part的序号
      * 读取图片
      * 读取clip数据
      * 读取sprite数据
      */
    loadXml(cpxml);

    tile_vct = new QVector<GraphicTile*>*[image_num];
    for (int a=0; a<image_num; a++){
        if (!images[a].image.load(pan.getFilePath()+"/"+images[a].image_name+".png")){
            QMessageBox::warning(this, tr("无法读取图片"), NULL);
            return;
        }
        if (images[a].image.format()!=QImage::Format_ARGB32){
            images[a].image.convertToFormat(QImage::Format_ARGB32);
        }
        tile_vct[a] = new QVector<GraphicTile*>;
        for (int i=0; i<images[a].clip_num; i++){
            GraphicTile *tile = new GraphicTile(
                        images[a].image,
                        images[a].clips[i].x,
                        images[a].clips[i].y,
                        images[a].clips[i].w,
                        images[a].clips[i].h);
            scene.addItem(tile);
            tile_vct[a]->append(tile);
        }
    }
    scene.update();

    if (lastdir!=pan.getFilePath()){
        lastdir = pan.getFilePath();
        QDomDocument setting;
        QDomElement root = setting.createElement("Setting");
        setting.appendChild(root);
        QDomElement path = setting.createElement("Path");
        root.appendChild(path);
        path.setAttribute("LastPath", lastdir);

        QString curdir = QApplication::applicationDirPath();
        QFile file(curdir+"\\"+"setting.xml");
        if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate |QIODevice::Text)){
            return;
        }
        QTextStream out(&file);
        out.setCodec(("UTF-8"));
        setting.save(out, 4);
        file.close();
    }
}

/**
  <entry>
    <IMAGE_TYPE>png</IMAGETYPE>
    <IMAGE_TILE>false</IMAGE_TILE>
    <IMAGE_GROUP>true</IMAGE_GROUP>
    <resource>
        <images  name  size>
            <clip index x y width height data />
            .....................
            <clip index x y width height data />
            <Append data/>
            <ImageInfo>
            </ImageInfo>
        </images>

        <sprite index name scene_part_count scene_frame_count cd_part_count cd_frame_count animate_count>
            <scene_part index tile x y trans alpha rotate scaleX scaleY />
            ....................................
            <scene_part index tile x y trans alpha rotate scaleX scaleY />


            <scene_frame index data_size data />
            ....................................
            <scene_frame index data_size data />


            <cd_part index type mask x1 y1 width height />
            ....................................
            <cd_part index type mask x1 y1 width height />


            <cd_frame index data_size data />
            ..................................
            <cd_frame index data_size data />


            <frames counts names animates cd_map />

            <Append data />
         </sprite>
    </resource>

    <level world_count />

  </entry>
  */
void CpcWindow::loadXml(QDomDocument &cpxml){

    QDomElement entry = cpxml.documentElement();   // entry
    QDomElement resource = entry.firstChildElement("resource");
    image_num = resource.attribute("images_count").toInt();
    sprite_num = resource.attribute("sprite_count").toInt();
    images = new ImageData[image_num];
    if (sprite_num!=0){
        sprites = new SpriteData[sprite_num];
    }else{
        sprites = NULL;
    }
    QDomElement images_e = resource.firstChildElement("images");
    QDomElement sprite_e = resource.firstChildElement("sprite");

    while (!images_e.isNull()){
        int img_index = images_e.attribute("index").toInt();
        images[img_index].image_name = images_e.attribute("name");
        images[img_index].clip_num = images_e.attribute("size").toInt();
        images[img_index].clips = new ST_rect[images[img_index].clip_num];
        QDomElement clip_e = images_e.firstChildElement();
        while (!clip_e.isNull()){
            int index = clip_e.attribute("index").toInt();
            images[img_index].clips[index].x = clip_e.attribute("x").toInt();
            images[img_index].clips[index].y = clip_e.attribute("y").toInt();
            images[img_index].clips[index].w = clip_e.attribute("width").toInt();
            images[img_index].clips[index].h = clip_e.attribute("height").toInt();
            clip_e = clip_e.nextSiblingElement("clip");
        }
        images_e = images_e.nextSiblingElement("images");
    }

    while (!sprite_e.isNull()){
        int spt_index = sprite_e.attribute("index").toInt();
        sprites[spt_index].spritename = sprite_e.attribute("name");
        sprites[spt_index].imagepakname = sprite_e.attribute("images_name");
        sprites[spt_index].imagepart_num = sprite_e.attribute("scene_part_count").toInt();
        sprites[spt_index].cdpart_num = sprite_e.attribute("cd_part_count").toInt();
        sprites[spt_index].anime_num = sprite_e.attribute("animate_count").toInt();
        sprites[spt_index].image_frame_num = sprite_e.attribute("scene_frame_count").toInt();
        sprites[spt_index].cd_frame_num = sprite_e.attribute("cd_frame_count").toInt();
        sprites[spt_index].image_parts = new ST_imagePart[sprites[spt_index].imagepart_num];
        sprites[spt_index].cd_parts = new ST_cdPart[sprites[spt_index].cdpart_num];
        sprites[spt_index].ifs = new ST_indexs[sprites[spt_index].image_frame_num];
        sprites[spt_index].cfs = new ST_indexs[sprites[spt_index].cd_frame_num];
        sprites[spt_index].animes = new ST_anime[sprites[spt_index].anime_num];

        QDomElement scene_part = sprite_e.firstChildElement("scene_part");
        while (!scene_part.isNull()){
            int sce_index = scene_part.attribute("index").toInt();
            ST_imagePart *imp=&(sprites[spt_index].image_parts[sce_index]);
            imp->image_index = scene_part.attribute("tile").toInt();
            imp->x = scene_part.attribute("x").toInt();
            imp->y = scene_part.attribute("y").toInt();
            imp->trans = scene_part.attribute("trans").toInt();
            imp->rotate = scene_part.attribute("rotate").toFloat();
            if (imp->rotate == 1){
                imp->rotate = 0;
            }
            imp->alpha = scene_part.attribute("alpha").toFloat();
            imp->scale_x = scene_part.attribute("scaleX").toInt();
            imp->scale_y = scene_part.attribute("scaleY").toInt();

            scene_part = scene_part.nextSiblingElement("scene_part");
        }

        QDomElement scene_frame = sprite_e.firstChildElement("scene_frame");
        while (!scene_frame.isNull()){
            int sf_index = scene_frame.attribute("index").toInt();
            ST_indexs *imf = &(sprites[spt_index].ifs[sf_index]);
            imf->num = scene_frame.attribute("data_size").toInt();
            imf->indexs = new int[imf->num];
            QStringList list = scene_frame.attribute("data").split(",", QString::SkipEmptyParts);
            for (int i=0; i<imf->num; i++){
                imf->indexs[i] = list.at(i).toInt();
            }
            scene_frame = scene_frame.nextSiblingElement("scene_frame");
        }

        QDomElement cd_part = sprite_e.firstChildElement("cd_part");
        while (!cd_part.isNull()){
            int cd_index = cd_part.attribute("index").toInt();
            ST_cdPart *cdp = &(sprites[spt_index].cd_parts[cd_index]);
            cdp->x1 = cd_part.attribute("x1").toInt();
            cdp->x2 = cd_part.attribute("x2").toInt();
            cdp->y1 = cd_part.attribute("y1").toInt();
            cdp->y2 = cd_part.attribute("y2").toInt();
            cdp->mask = cd_part.attribute("mask").toInt();
            cd_part = cd_part.nextSiblingElement("cd_part");
        }

        QDomElement cd_frame = sprite_e.firstChildElement("cd_frame");
        while (!cd_frame.isNull()){
            int cd_index = cd_frame.attribute("index").toInt();
            ST_indexs *cdf = &(sprites[spt_index].cfs[cd_index]);
            cdf->num = cd_frame.attribute("data_size").toInt();
            cdf->indexs = new int[cdf->num];
            QStringList list = cd_frame.attribute("data").split(",", QString::SkipEmptyParts);
            for (int i=0; i<cdf->num; i++){
                cdf->indexs[i] = list.at(i).toInt();
            }
            cd_frame = cd_frame.nextSiblingElement("cd_frame");
        }

        QDomElement frames = sprite_e.firstChildElement("frames");
        if (!frames.isNull()){
            QStringList list1 = frames.attribute("counts").split(",", QString::SkipEmptyParts);
            QStringList list2 = frames.attribute("names").split(",", QString::SkipEmptyParts);
            QStringList list3 = frames.attribute("animates").split("},", QString::SkipEmptyParts);
            QStringList list4 = frames.attribute("cd_map").split("},", QString::SkipEmptyParts);
            for (int i=0; i<sprites[spt_index].anime_num; i++){
                ST_anime *anm = &(sprites[spt_index].animes[i]);
                anm->frame_num = list1.at(i).toInt();
                anm->name = list2.at(i*2+1).toStdString();
                anm->image_frame_indexs = new int[anm->frame_num];
                anm->cd_frame_indexs = new int[anm->frame_num];
                QString ifis = list3.at(i).right(list3.at(i).size()-1);
                QString cfis = list4.at(i).right(list4.at(i).size()-1);
                QStringList ifislst = ifis.split(",", QString::SkipEmptyParts);
                QStringList cfislst = cfis.split(",", QString::SkipEmptyParts);
                for (int j = 0; j<anm->frame_num; j++){
                    anm->image_frame_indexs[j] = ifislst.at(j).toInt();
                    anm->cd_frame_indexs[j] = cfislst.at(j).toInt();
                }
            }
        }


        sprite_e = sprite_e.nextSiblingElement("sprite");
    }
}

void CpcWindow::clearWorkSpace(){
    if (image_num>0){
        for (int i=0; i<image_num; i++){
            delete[] images[i].clips;
            while (tile_vct[i]->size()>0){
                scene.removeItem(tile_vct[i]->at(0));
                delete tile_vct[i]->at(0);
                tile_vct[i]->remove(0);
            }
        }
        delete[] images;
        image_num = 0;
    }
    if (sprite_num>0){
        delete[] sprites;
    }

}

/** 把整图存成2进制
 *  1 int 块数量   存入clip文件
 *  2  块数组      存入clip文件
 *  3 int 颜色模式  存入clip文件
 *  4 int 图片宽 图片高
 *  5 int 图片数据大小
 *  6 u32* 图片像素数据
 */
void CpcWindow::convertImage(){
    bool is_need_completion = ui->checkBox->isChecked(); // 是否补齐2次幂
    int colormode = ui->comboBox->currentIndex(); // 0 RGBA8, 1 RGBA4, 2 RGB565, 3 ARGB8， 4 RGB8， 5 ARGB4

    for (int a=0; a<image_num; a++){
        QString filename = lastdir + images[a].image_name;
        QFile fileclip(filename+".clip");
        QFile filebin(filename+".bin");
        QFile filetxt(filename+".txt"); // 做参考用
        if (!fileclip.open(QFile::WriteOnly)){
            QMessageBox::warning(this, ("无法保存文件"+filename+".clip"), NULL);
            return;
        }
        if (!filebin.open(QFile::WriteOnly)){
            QMessageBox::warning(this, ("无法保存文件"+filename+".bin"), NULL);
            return;
        }
        if (!filetxt.open(QFile::WriteOnly | QFile::Text)){
            QMessageBox::warning(this, ("无法保存文件"+filename+".txt"), NULL);
            return;
        }
        QDataStream dsclip(&fileclip);
        QDataStream dsbin(&filebin);
        QTextStream tstxt(&filetxt);
        tstxt.setIntegerBase(10);
        dsclip.setByteOrder(QDataStream::LittleEndian);
        dsbin.setByteOrder(QDataStream::LittleEndian);

        dsclip<<images[a].clip_num;
    //    dsbin<<images[a].clip_num;
        tstxt<<"clip num = "<<images[a].clip_num<<endl;
        for (int i=0; i<images[a].clip_num; i++){
            dsclip<<images[a].clips[i].x;
            dsclip<<images[a].clips[i].y;
            dsclip<<images[a].clips[i].w;
            dsclip<<images[a].clips[i].h;

    //        dsbin<<clips[i]->x;
    //        dsbin<<clips[i]->y;
    //        dsbin<<clips[i]->w;
    //        dsbin<<clips[i]->h;

            tstxt<<"x="<<images[a].clips[i].x<<",";
            tstxt<<"y="<<images[a].clips[i].y<<",";
            tstxt<<"w="<<images[a].clips[i].w<<",";
            tstxt<<"h="<<images[a].clips[i].h<<endl;
        }
        dsclip<<colormode;
        dsbin<<colormode;
        tstxt<<"colormode = "<<colormode<<endl;

        // 图像数据输出开始
        const uchar* data = images[a].image.constBits();
        int img_width = images[a].image.width();
        int img_height = images[a].image.height();
        int out_width = img_width;
        int out_height = img_height;
        /** 是否按2次幂补全 */
        if (is_need_completion){
            out_width = 1 << getSmallest2exp(img_width);
            out_height = 1 << getSmallest2exp(img_height);
            if (out_width>1024) out_width = 1024;
            if (out_height>1024) out_height = 1024;
        }
        dsbin<<out_width;
        dsbin<<out_height;
        tstxt.setIntegerBase(16);
        uint32_t *p = (uint32_t*)data;
        for (int i=0; i<out_height; i++){
            for (int j=0; j<out_width; j++){
                if (i<img_height && j<img_width){
                    switch (colormode){
                    case 0: //RGBA8
                    {
                        uint32_t argb = p[j];
                        uchar a = (argb & (0xff<<24))>>24;
                        uint32_t rgba = (argb<<8) | a;
                        dsbin<<rgba;
                        tstxt<<rgba<<",";
                    }
                        break;
                    case 1: // RGBA4
                    {
                        uint32_t argb = p[j];
                        uint32_t b = (argb & 0xf0)>>4;
                        uint32_t g = (argb & (0xf0<<8))>>12;
                        uint32_t r = (argb & (0xf0<<16))>>20;
                        uint32_t a = (argb & (0xf0<<24))>>28;
                        ushort rgba4 = (ushort)((r<<12)|(g<<8)|(b<<4)|a);
                        dsbin<<rgba4;
                        tstxt<<rgba4<<",";
                    }
                        break;
                    case 2: // RGB565
                    {
                        uint32_t argb = p[j];
                        uchar b = (uchar)(argb & 0xff);
                        uchar g = (uchar)((argb & (0xff<<8))>>8);
                        uchar r = (uchar)((argb & (0xff<<16))>>16);
                        uint32_t a = (argb & (0xff<<24))>>24;
                        b = (uchar)(a*b/0xff)>>3;
                        g = (uchar)(a*g/0xff)>>2;
                        r = (uchar)(a*r/0xff)>>3;
                        ushort rgb565 = (ushort)((r<<11)+(g<<5)+b);
                        dsbin<<rgb565;
                        tstxt<<rgb565<<",";
                    }
                        break;
                    case 3: // ARGB8
                    {
                        dsbin<<p[j];
                        tstxt<<p[j]<<",";
                    }
                        break;
                    case 4: // RGB8
                    {
                        uint32_t argb = p[j];
                        uchar b = (uchar)(argb & 0xff);
                        uchar g = (uchar)((argb & (0xff<<8))>>8);
                        uchar r = (uchar)((argb & (0xff<<16))>>16);
                        uint32_t a = (argb & (0xff<<24))>>24;
                        b = (uchar)(a*b/0xff);
                        g = (uchar)(a*g/0xff);
                        r = (uchar)(a*r/0xff);
                        dsbin<<b;
                        dsbin<<g;
                        dsbin<<r;
                        tstxt<<b<<",";
                        tstxt<<g<<",";
                        tstxt<<r<<",";
                    }
                        break;
                    case 5: // ARGB4
                    {
                        uint32_t argb = p[j];
                        uint32_t b = (argb & 0xf0)>>4;
                        uint32_t g = (argb & (0xf0<<8))>>12;
                        uint32_t r = (argb & (0xf0<<16))>>20;
                        uint32_t a = (argb & (0xf0<<24))>>28;
                        ushort argb4 = (ushort)((a<<12)|(r<<8)|(g<<4)|b);
                        dsbin<<argb4;
                        tstxt<<argb4<<",";
                    }
                        break;
                    }
                }else{
                    switch (colormode){
                    case 0: // RGBA8
                    case 3: // ARGB8
                        dsbin<<(int)0;
                        tstxt<<"0x00000000,";
                        break;
                    case 4: // RGB8
                        dsbin<<(uchar)0;
                        dsbin<<(uchar)0;
                        dsbin<<(uchar)0;
                        tstxt<<"0x00,";
                        tstxt<<"0x00,";
                        tstxt<<"0x00,";
                        break;
                    case 1: // ARGB4
                    case 2: // RBG565
                        dsbin<<(ushort)0;
                        tstxt<<"0x0000,";
                        break;
                    }
                }
            }
            tstxt<<endl;
            if (i<img_height){
                p+=img_width;
            }
        }

        fileclip.close();
        filebin.close();
        filetxt.close();
    }
}

/** 把tile存成2进制
 * 1 int 块数量
 * 2 int 颜色模式
 * 3 int 图片宽 图片高 数据大小 u32* 图片像素数据     （图片宽高数据大小存入clip文件）
 * 4 int 图片宽 图片高 数据大小 u32* 图片像素数据
 *
 */
void CpcWindow::convertImageSplit(){
    bool is_need_completion = ui->checkBox->isChecked();
    int colormode = ui->comboBox->currentIndex(); // 0 RGBA8, 1 RGBA4, 2 RGB565, 3 ARGB8， 4 RGB8， 5 ARGB4

    for (int a=0; a<image_num; a++){
        QString filename = lastdir + images[a].image_name;
        QFile fileclip(filename+".clip");
        QFile filebin(filename+".bin");
        QFile filetxt(filename+".txt"); // 做参考用
        if (!fileclip.open(QFile::WriteOnly)){
            QMessageBox::warning(this, ("无法保存文件"+filename+".clip"), NULL);
            return;
        }
        if (!filebin.open(QFile::WriteOnly)){
            QMessageBox::warning(this, ("无法保存文件"+filename+".bin"), NULL);
            return;
        }
        if (!filetxt.open(QFile::WriteOnly|QFile::Text)){
            QMessageBox::warning(this, ("无法保存文件"+filename+".txt"), NULL);
            return;
        }
        QDataStream dsclip(&fileclip);
        QDataStream dsbin(&filebin);
        QTextStream tstxt(&filetxt);
        tstxt.setIntegerBase(10);
        dsclip.setByteOrder(QDataStream::LittleEndian);
        dsbin.setByteOrder(QDataStream::LittleEndian);

        dsclip<<images[a].clip_num;
    //    dsbin<<images[a].clip_num;
        tstxt<<"clip num = "<<images[a].clip_num<<endl;
        dsclip<<colormode;
    //    dsbin<<colormode;
        tstxt<<"color mode = "<<colormode<<endl;

        for (int i=0; i<images[a].clip_num; i++){
            QImage *tile = tile_vct[a]->at(i)->tile;
            const uchar* data = tile->constBits();
            int img_width = tile->width();
            int img_height = tile->height();
            int out_width = img_width;
            int out_height = img_height;
            /** 是否按2次幂补全 */
            if (is_need_completion){
                out_width = 1 << getSmallest2exp(img_width);
                out_height = 1 << getSmallest2exp(img_height);
                if (out_width>1024) out_width = 1024;
                if (out_height>1024) out_height = 1024;
            }
            int data_size = 0;
            switch (colormode){
            case 0: data_size = out_width*out_height*4;break;
            case 1: data_size = out_width*out_height*3;break;
            case 2: data_size = out_width*out_height*2;break;
            case 3: data_size = out_width*out_height*2;break;
            }

            dsclip<<out_width;
            dsclip<<out_height;
            dsclip<<data_size;
    //        dsbin<<out_width;
    //        dsbin<<out_height;
    //        dsbin<<data_size;
            tstxt.setIntegerBase(10);
            tstxt<<"tile_width = "<<out_width<<endl;
            tstxt<<"tile_height = "<<out_height<<endl;
            tstxt<<"data_size = "<<data_size<<endl;
            tstxt.setIntegerBase(16);
            uint32_t *p = (uint32_t*)data;
            for (int i=0; i<out_height; i++){
                for (int j=0; j<out_width; j++){
                    if (i<img_height && j<img_width){
                        switch (colormode){
                        case 0: //RGBA8
                        {
                            uint32_t argb = p[j];
                            uchar a = (argb & (0xff<<24))>>24;
                            uint32_t rgba = (argb<<8) | a;
                            dsbin<<rgba;
                            tstxt<<rgba<<",";
                        }
                            break;
                        case 1: // RGBA4
                        {
                            uint32_t argb = p[j];
                            uint32_t b = (argb & 0xf0)>>4;
                            uint32_t g = (argb & (0xf0<<8))>>12;
                            uint32_t r = (argb & (0xf0<<16))>>20;
                            uint32_t a = (argb & (0xf0<<24))>>28;
                            ushort rgba4 = (ushort)((r<<12)|(g<<8)|(b<<4)|a);
                            dsbin<<rgba4;
                            tstxt<<rgba4<<",";
                        }
                            break;
                        case 2: // RGB565
                        {
                            uint32_t argb = p[j];
                            uchar b = (uchar)(argb & 0xff);
                            uchar g = (uchar)((argb & (0xff<<8))>>8);
                            uchar r = (uchar)((argb & (0xff<<16))>>16);
                            uint32_t a = (argb & (0xff<<24))>>24;
                            b = (uchar)(a*b/0xff)>>3;
                            g = (uchar)(a*g/0xff)>>2;
                            r = (uchar)(a*r/0xff)>>3;
                            ushort rgb565 = (ushort)((r<<11)+(g<<5)+b);
                            dsbin<<rgb565;
                            tstxt<<rgb565<<",";
                        }
                            break;
                        case 3: // ARGB8
                        {
                            dsbin<<p[j];
                            tstxt<<p[j]<<",";
                        }
                            break;
                        case 4: // RGB8
                        {
                            uint32_t argb = p[j];
                            uchar b = (uchar)(argb & 0xff);
                            uchar g = (uchar)((argb & (0xff<<8))>>8);
                            uchar r = (uchar)((argb & (0xff<<16))>>16);
                            uint32_t a = (argb & (0xff<<24))>>24;
                            b = (uchar)(a*b/0xff);
                            g = (uchar)(a*g/0xff);
                            r = (uchar)(a*r/0xff);
                            dsbin<<b;
                            dsbin<<g;
                            dsbin<<r;
                            tstxt<<b<<",";
                            tstxt<<g<<",";
                            tstxt<<r<<",";
                        }
                            break;
                        case 5: // ARGB4
                        {
                            uint32_t argb = p[j];
                            uint32_t b = (argb & 0xf0)>>4;
                            uint32_t g = (argb & (0xf0<<8))>>12;
                            uint32_t r = (argb & (0xf0<<16))>>20;
                            uint32_t a = (argb & (0xf0<<24))>>28;
                            ushort argb4 = (ushort)((a<<12)|(r<<8)|(g<<4)|b);
                            dsbin<<argb4;
                            tstxt<<argb4<<",";
                        }
                            break;
                        }
                    }else{
                        switch (colormode){
                        case 0: // RGBA8
                        case 3: // ARGB8
                            dsbin<<(int)0;
                            tstxt<<"0x00000000,";
                            break;
                        case 4: // RGB8
                            dsbin<<(uchar)0;
                            dsbin<<(uchar)0;
                            dsbin<<(uchar)0;
                            tstxt<<"0x00,";
                            tstxt<<"0x00,";
                            tstxt<<"0x00,";
                            break;
                        case 1: // ARGB4
                        case 2: // RBG565
                            dsbin<<(ushort)0;
                            tstxt<<"0x0000,";
                            break;
                        }
                    }
                }
                tstxt<<endl;
                if (i<img_height){
                    p+=img_width;
                }
            }
        }


        fileclip.close();
        filebin.close();
        filetxt.close();
    }
}

/** 保存sprite数据为流 */
void CpcWindow::convertSprite(){
    for (int a=0; a<sprite_num; a++){
        QString filename = lastdir + sprites[a].spritename;
        QFile filesprite(filename+".spt");
        QFile filetxt(filename+".spt.txt");  //做参考用
        if (!filesprite.open(QFile::WriteOnly)){
            QMessageBox::warning(this, ("无法保存文件"+filename+".spt"), NULL);
            return;
        }
         if (!filetxt.open(QFile::WriteOnly | QFile::Text)){
            QMessageBox::warning(this, ("无法保存文件"+filename+".spt.txt"), NULL);
            return;
        }
        QDataStream dssprite(&filesprite);
        QTextStream txtsprite(&filetxt);
        dssprite.setByteOrder(QDataStream::LittleEndian);
        dssprite.setFloatingPointPrecision(QDataStream::SinglePrecision);
        string tstr = sprites[a].spritename.toStdString();
        int len = tstr.size()+1;
        len = ((len+3>>2)<<2);
//        int patch = ((len+3>>2)<<2)-len;
//        int c = 0;
        dssprite<<len;
        dssprite.writeRawData(tstr.c_str(), len);
//        dssprite.writeRawData((const char*)&c, patch);
        tstr = sprites[a].imagepakname.toStdString();
        len = tstr.size()+1;
        len = ((len+3>>2)<<2);
//        patch = ((len+3>>2)<<2)-len;
        dssprite<<len;
        dssprite.writeRawData(tstr.c_str(), len);
//        dssprite.writeRawData((const char*)&c, patch);

        txtsprite<<"spritename = "<<sprites[a].spritename<<endl;
        txtsprite<<"imagepakname = "<<sprites[a].imagepakname<<endl;

        //---------------image part----------------------
        int maxrange_x = sprites[a].image_parts[0].x;
        int maxrange_y = sprites[a].image_parts[0].y;
        int maxrange_x2 = sprites[a].image_parts[0].x;
        int maxrange_y2 = sprites[a].image_parts[0].y;
        dssprite<<sprites[a].imagepart_num;
        txtsprite<<"imagepart_num = "<<sprites[a].imagepart_num<<endl;
        for (int i=0; i<sprites[a].imagepart_num; i++){
//            dssprite<<sprites[a].image_parts[i].index;
            dssprite<<sprites[a].image_parts[i].image_index;
            dssprite<<sprites[a].image_parts[i].x;
            dssprite<<sprites[a].image_parts[i].y;
            dssprite<<sprites[a].image_parts[i].trans;
            dssprite<<sprites[a].image_parts[i].alpha;
            dssprite<<sprites[a].image_parts[i].rotate;
            dssprite<<sprites[a].image_parts[i].scale_x;
            dssprite<<sprites[a].image_parts[i].scale_y;

//            txtsprite<<"index = "<<sprites[a].image_parts[i].index<<endl;
            txtsprite<<"image_index = "<<sprites[a].image_parts[i].image_index<<endl;
            txtsprite<<"x = "<<sprites[a].image_parts[i].x<<endl;
            txtsprite<<"y = "<<sprites[a].image_parts[i].y<<endl;
            txtsprite<<"trans = "<<sprites[a].image_parts[i].trans<<endl;
            txtsprite<<"alpha = "<<sprites[a].image_parts[i].alpha<<endl;
            txtsprite<<"rotate = "<<sprites[a].image_parts[i].rotate<<endl;
            txtsprite<<"scale_x = "<<sprites[a].image_parts[i].scale_x<<endl;
            txtsprite<<"scale_y = "<<sprites[a].image_parts[i].scale_y<<endl;

            if (maxrange_x>sprites[a].image_parts[i].x){
                maxrange_x = sprites[a].image_parts[i].x;
            }
            if (maxrange_y>sprites[a].image_parts[i].y){
                maxrange_y = sprites[a].image_parts[i].y;
            }
            int img_w = images[a].clips[sprites[a].image_parts[i].image_index].w;
            int img_h = images[a].clips[sprites[a].image_parts[i].image_index].h;
            if (maxrange_x2<sprites[a].image_parts[i].x +img_w){
                maxrange_x2 = sprites[a].image_parts[i].x +img_w;
            }
            if (maxrange_y2<sprites[a].image_parts[i].y +img_h){
                maxrange_y2 = sprites[a].image_parts[i].y +img_h;
            }
        }
        //---------------------cd part--------------------------------
        dssprite<<sprites[a].cdpart_num;
        txtsprite<<"cdpart_name = "<<sprites[a].cdpart_num<<endl;
        for(int i=0; i<sprites[a].cdpart_num; i++){
//            dssprite<<sprites[a].cd_parts[i].index;
            dssprite<<sprites[a].cd_parts[i].mask;
            dssprite<<sprites[a].cd_parts[i].x1;
            dssprite<<sprites[a].cd_parts[i].y1;
            dssprite<<sprites[a].cd_parts[i].x2;
            dssprite<<sprites[a].cd_parts[i].y2;

//            txtsprite<<"index = "<<sprites[a].cd_parts[i].index<<endl;
            txtsprite<<"mask = "<<sprites[a].cd_parts[i].mask<<endl;
            txtsprite<<"x1 = "<<sprites[a].cd_parts[i].x1<<endl;
            txtsprite<<"y1 = "<<sprites[a].cd_parts[i].y1<<endl;
            txtsprite<<"x2 = "<<sprites[a].cd_parts[i].x2<<endl;
            txtsprite<<"y2 = "<<sprites[a].cd_parts[i].y2<<endl;
        }
        //-------------------image frame-------------------------------
        dssprite<<sprites[a].image_frame_num;
        txtsprite<<"image_frame_num = "<<sprites[a].image_frame_num<<endl;
        for (int i=0; i<sprites[a].image_frame_num; i++){
            dssprite<<sprites[a].ifs[i].num;
            dssprite.writeRawData(
                        (const char*)(sprites[a].ifs[i].indexs),
                        sprites[a].ifs[i].num*4);

            txtsprite<<"image index len = "<<sprites[a].ifs[i].num<<endl;
            txtsprite<<"indexs = ";
            for (int j=0; j<sprites[a].ifs[i].num; j++){
                txtsprite<<sprites[a].ifs[i].indexs[j]<<",";
            }
            txtsprite<<endl;
        }
        //-----------------cd frame--------------------------------------
        dssprite<<sprites[a].cd_frame_num;
        txtsprite<<"cd_frame_num = "<<sprites[a].cd_frame_num<<endl;
        for (int i=0; i<sprites[a].cd_frame_num; i++){
            dssprite<<sprites[a].cfs[i].num;
            dssprite.writeRawData(
                        (const char*)(sprites[a].cfs[i].indexs),
                        sprites[a].cfs[i].num*4);

            txtsprite<<"cd index len = "<<sprites[a].cfs[i].num<<endl;
            txtsprite<<"indexs = ";
            for (int j=0; j<sprites[a].cfs[i].num; j++){
                txtsprite<<sprites[a].cfs[i].indexs[j]<<",";
            }
            txtsprite<<endl;
        }
        //------------------anime--------------------------------------
        dssprite<<sprites[a].anime_num;
        txtsprite<<"anime_num = "<<sprites[a].anime_num<<endl;
        for (int i=0; i<sprites[a].anime_num; i++){
            len = sprites[a].animes[i].name.size()+1;
            len = ((len+3>>2)<<2);
            dssprite<<len;
            dssprite.writeRawData(sprites[a].animes[i].name.c_str(), len);
//            dssprite.writeRawData((const char*)&c, patch);

            dssprite<<sprites[a].animes[i].frame_num;
            dssprite.writeRawData(
                        (const char*)(sprites[a].animes[i].image_frame_indexs),
                        sprites[a].animes[i].frame_num*4);
            dssprite.writeRawData(
                        (const char*)(sprites[a].animes[i].cd_frame_indexs),
                        sprites[a].animes[i].frame_num*4);

            txtsprite<<"anime name = "<<sprites[a].animes[i].name.c_str()<<endl;
            txtsprite<<"frame num = "<<sprites[a].animes[i].frame_num<<endl;
            txtsprite<<"indexs = ";
            for (int j=0; j<sprites[a].animes[i].frame_num; j++){
                txtsprite<<sprites[a].animes[i].image_frame_indexs[j]<<",";
            }
            txtsprite<<endl;
        }
        dssprite<<maxrange_x;
        dssprite<<maxrange_y;
        dssprite<<maxrange_x2-maxrange_x;
        dssprite<<maxrange_y2-maxrange_y;

        txtsprite<<maxrange_x;
        txtsprite<<maxrange_y;
        txtsprite<<maxrange_x2-maxrange_x;
        txtsprite<<maxrange_y2-maxrange_y;
        txtsprite<<endl;

        filesprite.close();
        filetxt.close();
    }
}

void CpcWindow::cexit(){
    exit(0);
}


int CpcWindow::getSmallest2exp(int n){
    int b = 0;
    while((1<<b)<n){
        b+=1;
    }
    return b;
}
